/*
 * @Author: WuFeng <763467339@qq.com>
 * @Date: 2022-03-22 12:12:49
 * @LastEditTime: 2023-05-18 18:02:55
 * @LastEditors: WuFeng <763467339@qq.com>
 * @Description: 鉴权
 * @FilePath: \vue3-element-plus-web\src\store\modules\permission.js
 * @Copyright 版权声明
 */
import { constantRouterMap } from '@/router'
import componentConfigs from '@/router/componentConfigs'
import { trim } from '@/utils'

// 路由组件 懒加载
const loadView = (view) => {
  if (process.env.NODE_ENV === 'development') {
    // 本地开发环境使用 require 实现路由懒加载， 解决热更新慢问题
    return require.ensure([], (require) => require(`@/views${view}`))
    // return (resolve) => require([`@/views${view}`], resolve)
    // return () => import(`@/views${view}.vue`)
  } else {
    // 使用 import 实现生产环境的路由懒加载
    return () => import(`@/views${view}.vue`)
  }
}

/**
 * 处理菜单数据，给只有一级的加一层
 * @param {*} menus
 */
function generateMenus(menus) {
  const menusRoute = []
  for (const i in menus) {
    const item = menus[i]
    const itemTemp = {
      path: '/a' + i,
      component: 'Layout',
      meta: {
        top: true,
        title: 'a' + i
      },
      hidden: item.hidden,
      name: '',
      children: [],
      // iframeRender: i === '0'
      iframeRender: !!((typeof item.iframeRender !== 'undefined' && item.iframeRender === true))
    }
    itemTemp.children.push(item)
    menusRoute.push(itemTemp)
  }
  return menusRoute
}

/**
 * 递归过滤异步路由表，返回用户权限菜单的路由表
 * @param {*} menus
 */
function generateAsyncRouter(menus) {
  const accessedRouters = []
  for (const i in menus) {
    const item = menus[i]
    const itemTemp = {}
    itemTemp.path = item.path
    itemTemp.fullpath = item.fullpath || item.path
    if (
      typeof item.iframeRender !== 'undefined' &&
      item.iframeRender === true
    ) {
      itemTemp.iframeRender = true
    }
    if (item.name !== '') {
      itemTemp.name = item.name
    }
    itemTemp.hidden = item.hidden
    itemTemp.meta = item.meta
    item.component = trim(item.component) // trim component属性前后空格
    // 如果菜单是在本系统中通过vue-router方式打开
    // if (itemTemp.meta.isOpen !== true) {
    // 如果组件不存在
    if (item.component !== '') {
      // 组件匹配
      const componentStr = item.component.replace(/\./g, '_').toUpperCase()
      const componentObj = componentConfigs[componentStr]
      // 如果当前遍历的路由组件在 componentConfig.js 配置中不存在使用 loadView() 方法自动加载
      if (typeof componentObj === 'undefined') {
        let itemTempPath = ''
        if ((itemTemp.path).indexOf('?') > -1) { // 路由携带参数
          const itemTempPathArr = ((itemTemp.path).split('?'))
          itemTempPath = itemTempPathArr[0]
          const itemTempPathQuery = itemTempPathArr[1]
          itemTemp.path = `${itemTempPath}/a${i}`
          itemTemp.name = `${itemTemp.name}`
          itemTemp.fullpath = `${itemTempPath}/a${i}?${itemTempPathQuery}`
          itemTemp.noCache = true
        } else if ((itemTemp.path).indexOf(':') > -1) { // 路由动态参数
          itemTempPath = (itemTemp.path).substring(0, ((itemTemp.path).indexOf(':') - 1))
          const trendsParams = (itemTemp.path).substring(((itemTemp.path).indexOf(':') - 1), (itemTemp.path).length)
          itemTemp.path = `${itemTempPath}/a${i}${trendsParams}`
          itemTemp.name = `${itemTemp.name}`
          itemTemp.fullpath = `${itemTempPath}/a${i}${trendsParams}`
        } else {
          itemTempPath = itemTemp.path
          itemTemp.fullpath = itemTemp.path
        }
        itemTemp.component = loadView(itemTempPath)
      } else {
        itemTemp.component = componentObj
      }
    }
    // }
    if (item.children && item.children.length) {
      // 递归调用
      itemTemp.children = generateAsyncRouter(item.children)
    }
    accessedRouters.push(itemTemp)
  }
  return accessedRouters
}

// 递归+闭包找到所有的最后一级
function getChild(data) {
  const maps = []
  // 定义一个函数
  function xxx(data) {
    if (data.children && data.children.length) {
      for (let i = 0, len = data.children.length; i < len; i++) {
        xxx(data.children[i])
      }
    } else {
      maps[data.name] = data
    }
    return maps
  }
  for (const item of data) {
    xxx(item)
  }
  return maps
}

/**
 * 将子路由转换为扁平化路由数组（仅一级）
 * @param {待转换的子路由数组} routes
 * @param {父级路由路径} parentPath
 */
function castToFlatRoute(routes, parentPath, flatRoutes = []) {
  for (const item of routes) {
    if (item.children && item.children.length > 0) {
      if (item.redirect && item.redirect !== 'noRedirect') {
        flatRoutes.push(item)
      }
      castToFlatRoute(item.children, parentPath + '/' + item.path, flatRoutes)
    } else {
      flatRoutes.push(item)
    }
  }

  return flatRoutes
}

/**
 * 将路由树转换为两级扁平化路由数组（仅第一级 和 最后一级）
 * @param {动态菜单的路由表集合} accessRoutes
 */
function generateFlatRoutes(accessRoutes) {
  const flatRoutes = []

  for (const item of accessRoutes) {
    let childrenFflatRoutes = []
    if (item.children && item.children.length > 0) {
      childrenFflatRoutes = castToFlatRoute(item.children, '')
    }

    // 一级路由是布局路由,需要处理的只是其子路由数据
    flatRoutes.push({
      ...item,
      children: childrenFflatRoutes
    })
  }

  return flatRoutes
}

const permission = {
  state: {
    authRouters: [], //权限系统菜单
    routers: constantRouterMap, // 所有路由
    routersMap: {}, // 所有末级路由的map，key为路由的name
    addRouters: [], // 动态生成的动态路由
    iframeHref: '', //iframe模式引用的src
    sidebarTopActive: '1' //当前选中的头部导航
  },
  mutations: {
    // 运营系统路由
    SET_ROUTERS: (state, routers) => {
      // state.addRouters = routers
      state.addRouters = generateFlatRoutes(routers)
      state.routers = constantRouterMap.concat(routers)
      state.routersMap = getChild(state.routers)
    },
    // 权限系统路由
    SET_AUTH_ROUTERS: (state, routers) => {
      state.authRouters = routers
    },
    SET_IFRAME_HREF: (state, url) => {
      state.iframeHref = url
    },
    SET_SIDEBAR_TOP_ACTIVE: (state, active) => {
      state.sidebarTopActive = active
    }
  },
  actions: {
    GenerateRoutes({ commit }, data) {
      return new Promise((resolve) => {
        // 运营管理平台菜单
        // const menus = data.menus.self
        const menus = data.menus
        const menusRoute = generateMenus(menus)
        const accessedRouters = generateAsyncRouter(menusRoute)
        accessedRouters.push({ path: '/:catchAll(.*)', redirect: '/404', hidden: true })
        commit('SET_ROUTERS', accessedRouters)
        // 集成权限系统菜单
        // const authMenus = data.menus.auth
        const authMenus = []
        commit('SET_AUTH_ROUTERS', authMenus)
        resolve()
      })
    },
    // 设置iframe的src
    SetIframeHref({ commit }, data) {
      return new Promise((resolve) => {
        commit('SET_IFRAME_HREF', data)
        resolve()
      })
    },
    // 设置当前选中的头部导航
    SetSidebarTopActive({ commit }, data) {
      return new Promise((resolve) => {
        commit('SET_SIDEBAR_TOP_ACTIVE', data)
        resolve()
      })
    }
  }
}

export default permission
